//
//  ViewController.m
//  NSURLSessionDownloadTaskDemo
//
//  Created by sheepyellow on 2017/3/18.
//  Copyright © 2017年 sheepyellow. All rights reserved.
//

#import "ViewController.h"
#import "AppDelegate.h"
@interface ViewController ()<NSURLSessionDownloadDelegate>
/* NSURLSession */
@property (strong, nonatomic) NSURLSession* currentSession;             //当前会话
@property (strong, nonatomic, readonly) NSURLSession* backgroundSession;//后台会话

/* 下载任务 */
@property (strong, nonatomic) NSURLSessionDownloadTask* cancellableTask;//可取消的下载任务

@property (strong, nonatomic) NSURLSessionDownloadTask* resumableTask; //可恢复的下载任务

@property (strong, nonatomic) NSURLSessionDownloadTask* backgroundTask; //后台的下载任务

/* 用于可恢复的下载任务的数据 */
@property (strong, nonatomic) NSData* partialData;

/* 显示已经下载的图片 */
@property (weak, nonatomic) IBOutlet UIImageView *downloadedImageView;

/* 下载进度 */
@property (strong, nonatomic) IBOutlet UILabel *currentProgress_label;
@property (strong, nonatomic) IBOutlet UIProgressView *downloadingProgressView;

/* 工具栏上的按键 */

@property (strong, nonatomic) IBOutlet UIBarButtonItem *cancelableDownload_barButtonItem;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *resumableDownload_barButtonItem;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *backgroundDownload_barButtonItem;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *cancelTask_barButtonItem;

@end

#define kCurrentSession @"kCurrentSession"
#define kBackgroundSessionID @"com.yourcompany.appId.BackgroundSession"
#define kBackgroundSession @"kBackgroundSession"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


- (IBAction)cancellableDownload:(id)sender { // 创建可取消的下载任务

    if (!self.cancellableTask) {
        if (!self. currentSession) {
            [self creatCurrentSession];
        }
        
        NSString* stringURLStr = @"http://farm6.staticflickr.com/5505/9824098016_0e28a047c2_b_d.jpg";
        NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:stringURLStr]];
        self.cancellableTask = [self.currentSession downloadTaskWithRequest:request];
        
        [self setDownloadButtonsWithEnabled:YES];
        self.downloadedImageView.image = nil;
        
        [self.cancellableTask resume];
    }
}
- (IBAction)resumableDownload:(id)sender   // 创建可恢复的下载任务
{
    if (!self.resumableTask) {
        if (!self.currentSession) {
            [self creatCurrentSession];
        }
        
        if (self.partialData) {
            self.resumableTask = [self.currentSession downloadTaskWithResumeData:self.partialData];
        }
        else { //否则创建下载任务
            NSString* imageURLStr = @"http://farm3.staticflickr.com/2846/9823925914_78cd653ac9_b_d.jpg";
            NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURLStr]];
            self.resumableTask = [self.currentSession downloadTaskWithRequest:request];
        }
        
        [self setDownloadButtonsWithEnabled:YES];
        self.downloadedImageView.image = nil;
        
        [self.resumableTask resume];
    }
}

- (IBAction)backgroundDownload:(id)sender  // 创建后台下载任务
{
    NSString *imageURLStr = @"http://farm3.staticflickr.com/2831/9823890176_82b4165653_b_d.jpg";
    NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURLStr]];
    self.backgroundTask = [self.backgroundSession downloadTaskWithRequest:request];
    [self setDownloadButtonsWithEnabled:YES];
    self.downloadedImageView.image = nil;
    [self.backgroundTask resume];
}

- (IBAction)cancelDownloadTask:(id)sender  // 取消所有下载任务
{
    if (self.cancellableTask) {
        [self.cancellableTask cancel];
        self.cancellableTask = nil;
        [self setDownloadButtonsWithEnabled:NO];
    }
    else if(self.resumableTask) {
        [self.resumableTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
            // 如果是可恢复的下载任务，应该先将数据保存到partialData中，注意在这里不要调用cancel方法
            
            self.partialData = resumeData;
            self.resumableTask = nil;
        }];
    }
    else if(self.backgroundTask) {
        [self.backgroundTask cancel];
        self.backgroundTask = nil;
    }
}

-(void)creatCurrentSession {
    NSURLSessionConfiguration* defaultConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
    self.currentSession = [NSURLSession sessionWithConfiguration:defaultConfig delegate:self delegateQueue:nil];
    self.currentSession.sessionDescription = kCurrentSession;
}

-(void)setDownloadButtonsWithEnabled:(BOOL) b{
    self.cancelTask_barButtonItem.enabled = b;
}

/* 根据下载进度更新视图 */
- (void)setDownloadProgress:(double)progress {
    NSString *progressStr = [NSString stringWithFormat:@"%.1f", progress * 100];
    progressStr = [progressStr stringByAppendingString:@"%"];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        self.downloadingProgressView.progress = progress;
        self.currentProgress_label.text = progressStr;
    });
}


-(NSURLSession *)backgroundSession {
    static NSURLSession* backgroundSess = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration* config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:kBackgroundSessionID];
        backgroundSess = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
        backgroundSess.sessionDescription = kBackgroundSession;
    });
    return backgroundSess;
}

-(NSString *)getDocumentsPath {
    NSArray* documents = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentPath = documents[0];
    return documentPath;
}

#pragma mark - NSURLSessionDownloadDelegate

-(void)URLSession:(NSURLSession *)session
     downloadTask:(NSURLSessionDownloadTask *)downloadTask
didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes {
    NSLog(@"NSURLSessionDownloadDelegate: Resume download at %lld",fileOffset);
}

-(void)saveandshowDownImageWithURL:(NSURL*)location fileName:(NSString*)fileName {
    NSString* documentPath = [self getDocumentsPath];
    NSURL* documentsDirectoryURL = [NSURL fileURLWithPath:documentPath];
    NSURL* fileURL = [documentsDirectoryURL URLByAppendingPathComponent:fileName];
    // 如果该路径下文件已经存在，就要像将其移除，在移除文件
    NSFileManager* fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:[fileURL path] isDirectory:NULL]) {
        [fileManager removeItemAtURL:fileURL error:NULL];
    }
    [fileManager moveItemAtURL:location toURL:fileURL error:NULL];
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            __strong NSString* path = fileURL.absoluteString;
            path = [path stringByReplacingOccurrencesOfString:@"file://" withString:@""];
            NSLog(@"%@",path);
            UIImage* image = [UIImage imageWithContentsOfFile:path];
            self.downloadedImageView.image = image;
        });
    }
    else {
        __strong NSString* path = fileURL.absoluteString;
        path = [path stringByReplacingOccurrencesOfString:@"file://" withString:@""];
        NSLog(@"%@",path);
        UIImage* image = [UIImage imageWithContentsOfFile:path];
        self.downloadedImageView.image = image;
    }
}

-(void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location {
    if (session == self.currentSession) {
        
        [self saveandshowDownImageWithURL:location fileName:[[downloadTask.response URL] lastPathComponent]];
    }
    else if(session == self.backgroundSession) {
        self.backgroundTask = nil;
        AppDelegate* appDelegate = [AppDelegate sharedDelegate];
        if (appDelegate.backgroundURLSessionCompletionHandler) {
            //执行回调代码块
            void(^ handler)() = appDelegate.backgroundURLSessionCompletionHandler;
            appDelegate.backgroundURLSessionCompletionHandler = nil;
            handler();
            [self setDownloadProgress:1.0f];
            [self saveandshowDownImageWithURL:location fileName:[[downloadTask.response URL] lastPathComponent]];
        }
        
    }
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error {
    NSLog(@"NSURLSessionDownloadDelegate: Complete task");
    dispatch_async(dispatch_get_main_queue(), ^{
        [self setDownloadButtonsWithEnabled:NO];
    });
    
    if (error) {
        NSLog(@"下载失败: %@",error);
        [self setDownloadProgress:0.0];
        self.downloadedImageView.image = nil;
    }

}

- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    double downloadProgress = totalBytesWritten / (double)totalBytesExpectedToWrite;
    [self setDownloadProgress:downloadProgress];
}



@end
